From 9e2207b2b0d1a8c5bdca8f56f370750b4c791204 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jonas=20=C3=85dahl?= Date: Fri, 26 Feb 2016 14:10:06 +0800 Subject: [PATCH] gdk: Compress window state events If there are already a window state event for a given window queued when the window state is changed, drop that event and queue a new event with a changed_mask based on the state before last event that was queue without compression. https://bugzilla.gnome.org/show_bug.cgi?id=762468 --- gdk/gdkevents.c | 39 +++++++++++++++++++++++++++++++++++---- gdk/gdkinternals.h | 1 + 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index 827b03a5c2..a094d4aad3 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -2159,12 +2159,32 @@ _gdk_event_button_generate (GdkDisplay *display, } } +static GList * +gdk_get_pending_window_state_event_link (GdkWindow *window) +{ + GdkDisplay *display = gdk_window_get_display (window); + GList *tmp_list; + + for (tmp_list = display->queued_events; tmp_list; tmp_list = tmp_list->next) + { + GdkEventPrivate *event = tmp_list->data; + + if (event->event.type == GDK_WINDOW_STATE && + event->event.window_state.window == window) + return tmp_list; + } + + return NULL; +} + void _gdk_set_window_state (GdkWindow *window, GdkWindowState new_state) { + GdkDisplay *display = gdk_window_get_display (window); GdkEvent temp_event; GdkWindowState old; + GList *pending_event_link; g_return_if_fail (window != NULL); @@ -2173,11 +2193,22 @@ _gdk_set_window_state (GdkWindow *window, temp_event.window_state.send_event = FALSE; temp_event.window_state.new_window_state = new_state; - old = window->state; - - if (temp_event.window_state.new_window_state == old) + if (temp_event.window_state.new_window_state == window->state) return; /* No actual work to do, nothing changed. */ + pending_event_link = gdk_get_pending_window_state_event_link (window); + if (pending_event_link) + { + old = window->old_state; + _gdk_event_queue_remove_link (display, pending_event_link); + g_list_free_1 (pending_event_link); + } + else + { + old = window->state; + window->old_state = old; + } + temp_event.window_state.changed_mask = new_state ^ old; /* Actually update the field in GdkWindow, this is sort of an odd @@ -2199,7 +2230,7 @@ _gdk_set_window_state (GdkWindow *window, { case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_TEMP: /* ? */ - gdk_display_put_event (gdk_window_get_display (window), &temp_event); + gdk_display_put_event (display, &temp_event); break; case GDK_WINDOW_FOREIGN: case GDK_WINDOW_ROOT: diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index ad1947eb21..2edc20472f 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -315,6 +315,7 @@ struct _GdkWindow /* We store the old expose areas to support buffer-age optimizations */ cairo_region_t *old_updated_area[2]; + GdkWindowState old_state; GdkWindowState state; guint8 alpha; -- 2.30.2